﻿using System;
using Community.CsharpSqlite.WP.SqliteDataProvider.Base;
using Community.CsharpSqlite.WP.SqliteDataProvider.Exceptions;

namespace Community.CsharpSqlite.WP.SqliteDataProvider
{
    /// <summary>
    /// Sqlite Connection
    /// </summary>
    public class SqliteConnection : IDbConnection,  IDisposable
    {
        private bool _isDisposed;
        private Sqlite3.sqlite3 _db;

        /// <summary>
        /// Gets or sets the handle.
        /// </summary>
        /// <value>The handle.</value>
        public Sqlite3.sqlite3 Handle { get { return _db; } }

        /// <summary>
        /// Gets or sets the connection string.
        /// </summary>
        /// <value>The connection string.</value>
        public string ConnectionString { get; set; }

        /// <summary>
        /// Gets or sets the state.
        /// </summary>
        /// <value>The state.</value>
        public ConnectionState State { get; set; }

        /// <summary>
        /// Gets or sets the database.
        /// </summary>
        /// <value>The database.</value>
        public string Database { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="SqliteConnection"/> class.
        /// </summary>
        /// <param name="connectionString">The connection string.</param>
        public SqliteConnection(string connectionString)
        {
            ConnectionString = connectionString;
        }

        public void Open()
        {
            _db = new Sqlite3.sqlite3();

            if (Sqlite3.sqlite3_open(ConnectionString, ref _db) != 0)
            {
                var errorMessage = string.Format(
                    "Cannot open database: {0}",
                    Sqlite3.sqlite3_errmsg(_db));

                _db = null;
                State = ConnectionState.Closed;
                throw new SqliteConnectionException(errorMessage);
            }
            State = ConnectionState.Open;
        }

        public void Close()
        {
            if (_db != null)
            {
                if (Sqlite3.sqlite3_close(_db) != 0)
                {
                    var errorMessage = string.Format(
                        "Cannot close database: ",
                        Sqlite3.sqlite3_errmsg(_db));

                    _db = null;

                    State = ConnectionState.Closed;
                    throw new SqliteConnectionException(errorMessage);
                }
                State = ConnectionState.Closed;
            }
        }


        public void Dispose()
        {
            Dispose(true);
        }


        private void Dispose(bool isDisposed)
        {
            // Ensure we only dispose of once
            if (_isDisposed)
                return;

            // Set flag indicating we disposed this instance
            _isDisposed=isDisposed;

            // close the database
            Close();
        }


        
        public IDbCommand CreateCommand()
        {
            throw new NotImplementedException();
        }


        #region NOT IMPLEMENTED 
        public IDbTransaction BeginTransaction(IsolationLevel iso)
        {
            throw new NotImplementedException();
        }
        public IDbTransaction BeginTransaction()
        {
            throw new NotImplementedException();
        }
        public bool ChangeDatabase(string newdb)
        {
            throw new NotImplementedException();
        }
        public int ConnectionTimeout
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }
        #endregion


    }
}
